package main

import (
	"flag"
	"fmt"
	"io"
	"net"
	"os"
)

// client客户端结构体
type client struct {
	ServerIP   string
	ServerPort int
	Name       string
	conn       net.Conn
	flag       int //菜单flag
}

// 命令行 接受 ip 和 port 自定义连接的服务器
var serverPort int
var serverIp string

func init() {
	flag.StringVar(&serverIp, "ip", "127.0.0.1", "设置默认的IP地址是：127。0。0。1")
	flag.IntVar(&serverPort, "port", 8888, "默认的端口号是：8888")
}

// 创建client对象
func NewClient(serverIp string, serverPort int) *client {
	//创建客户端对象
	client := &client{
		ServerIP:   serverIp,
		ServerPort: serverPort,
		flag:       9999,
	}
	//连接server
	conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", serverIp, serverPort))
	if err != nil {
		fmt.Println("net.Dail error:", err)
		return nil
	}

	//返回对象
	client.conn = conn
	return client
}

// 菜单代码
func (client *client) menu() bool {
	var flag int
	fmt.Println("1.广播模式")
	fmt.Println("2.私聊模式")
	fmt.Println("3.更新用户名")
	fmt.Println("0.退出")
	fmt.Scanln(&flag)
	if flag > 0 && flag <= 3 {
		client.flag = flag
		return true
	} else {
		fmt.Println(">>>>>>>>>>.请输入合法范围内的数字")
		return false
	}
}

func (client *client) UpdateName() bool {
	fmt.Println(">>>>>>>>>>.请输入用户名>>>>>")
	fmt.Scanln(&client.Name)
	sendMsg := "rename|" + client.Name + "\n"
	_, err := client.conn.Write([]byte(sendMsg))
	if err != nil {
		fmt.Println("conn write err:", err)
		return false
	}
	return true
}

/*
*
测试的时候需要将maina函数名变更为main
并和main.go文件中的mian函数单独分开运行
*/
func main() {

	//有关命令行的解析
	flag.Parse()

	//连接服务器
	client := NewClient(serverIp, serverPort)
	if client == nil {
		fmt.Println(">>>>>>>>>>>>连接服务器失败...")
		return
	}
	fmt.Println(">>>>>>>>>>>>>连接服务器成功")
	//等待客户端的返回的消息
	go client.DealResponse()

	//启动客户端的业务
	client.Run()
}

// 广播模式
func (client *client) PublicCaht() {
	//提示用户输入消息
	var chatMsg string
	fmt.Println(">>>>>>>>>>>>>..请输入聊天内容，exit退出")
	fmt.Scanln(&chatMsg)
	for chatMsg != "exit" {
		//发送给服务器
		//消息不为空则发送
		if len(chatMsg) != 0 {
			sendMsg := chatMsg + "\n"
			//命令行发送信息到服务器
			_, err := client.conn.Write([]byte(sendMsg))
			if err != nil {
				fmt.Println("conn write err:", err)
				break
			}
		}

		chatMsg = ""
		fmt.Println(">>>>>>>>>>>>>..请输入聊天内容，exit退出")
		fmt.Scanln(&chatMsg)
	}
}

// 业务逻辑代码
func (client *client) Run() {
	for client.flag != 0 {
		for client.menu() != true {
		} //根据不同模式处理不同的业务
		switch client.flag {
		case 1:
			fmt.Println("您已经选择广播模式")
			client.PublicCaht()
			break
		case 2:
			fmt.Println("您已经选择私聊模式")
			client.PrivateChat()
			break
		case 3:
			fmt.Println("更新用户信息")
			client.UpdateName()
			break
		}
	}
}

// 查询在线用户
func (client *client) Selectusers() {
	sendMsg := "whoonline\n"
	//将服务端的信息打印到命令行
	_, err := client.conn.Write([]byte(sendMsg))
	if err != nil {
		fmt.Println("conn write err:", err)
		return
	}

}

// 私聊模式
func (client *client) PrivateChat() {
	var remoteName string
	var chatMsg string

	client.Selectusers()
	fmt.Println("请输入聊天用户的用户名 exit退出")
	fmt.Scanln(&remoteName)
	for remoteName != "exit" {
		fmt.Println("请输入消息内容，exit退出")
		fmt.Scanln(&chatMsg)

		for chatMsg != "exit" {
			if len(chatMsg) != 0 {
				sendMsg := "to|" + remoteName + "|" + chatMsg + "\n\n"
				_, err := client.conn.Write([]byte(sendMsg))
				if err != nil {
					fmt.Println("conn write err:", err)
					break
				}
			}
			chatMsg = ""
			fmt.Println("请输入消息内容，exit退出")
			fmt.Scanln(&chatMsg)
		}
		client.Selectusers()
		fmt.Println("请输入聊天用户的用户名 exit退出")
		fmt.Scanln(&remoteName)
	}
}

// 处理server回应的消息
func (client *client) DealResponse() {
	io.Copy(os.Stdout, client.conn)
}
